package com.example.securitydemo2.config;

import com.example.securitydemo2.service.SecurityUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


@Configuration   //被spring所识别   为工具类
@EnableGlobalMethodSecurity(prePostEnabled = true)  //授权的开启
public class SecurityConfig extends WebSecurityConfigurerAdapter {

//    用户配置      用户---角色---权限
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication()
//                .withUser("admin").roles("admin").password("$2a$10$b7QZPNX45ouwdh50qeK7zueRBCCWmT1DDHH7cZR4t7.UU4H02rMc6")
//                .and()
//                .withUser("user").roles("user").password("$2a$10$b7QZPNX45ouwdh50qeK7zueRBCCWmT1DDHH7cZR4t7.UU4H02rMc6");
    auth
            .userDetailsService(securityUserService()) //注入的为方法
            .passwordEncoder(bCryptPasswordEncoder());

    }
//    密文加密
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityUserService securityUserService(){
        return new SecurityUserService();
    }

    public static void main(String[] args) {
//        加密策略   MD5不安全
        String paranoid = new BCryptPasswordEncoder().encode("000");
        System.out.println(paranoid);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);

//        web.ignoring().antMatchers("/js/**");
    }

    /**
     *     核心配置    登录配置
     */

//    @Autowired
//    private SecurityUserService securityUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http
//                .userDetailsService(securityUserService);   //登录验证方法  未加密

        /***
         * 普通的登录角色权限验证
         */
//        http.authorizeRequests() //开启登录配置
//                .antMatchers("/get-all").hasRole("admin")   ///get-all接口必须拥有admin的权限
//                .anyRequest().authenticated()  //剩下的所有请求登录即可访问
//                .and().formLogin().permitAll()  //表单登录放行
//                .and().logout().permitAll()  //登出放行
//                .and().httpBasic();    //基于http的访问也有登录的授权

        http.authorizeRequests()
//                .antMatchers("/get-all").hasRole("admin")  ///get-all接口必须拥有admin的权限
                .antMatchers("/login").permitAll()   //登录接口放行
                .anyRequest().access("@authService.auth(request,authentication)")
//                .anyRequest().authenticated()  //剩下的所有请求登录即可访问
                .and().formLogin()
                .loginPage("/login.html")   //自定义登录页面
                .loginProcessingUrl("/login")   //登录处理接口
                .usernameParameter("username")  //登录页面传过来的用户名   username
                .passwordParameter("password")  //登录页面传过来的密码//  password
                .successHandler(new AuthenticationSuccessHandler() {    //登录成功后的操作     处理器
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("success");
                    }
                })
                .failureHandler(new AuthenticationFailureHandler() {    //登录失败处理     处理器
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("fail");
                    }
                })
                .permitAll()  //通过  不拦截
                .and().logout() //退出登录
                .logoutUrl("/logout")
                .logoutSuccessHandler(new LogoutSuccessHandler() {    //登出成功    处理器
                    @Override
                    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=utf-8");
                        PrintWriter out = httpServletResponse.getWriter();
                        out.write("logout success");
                    }
                })
                .permitAll()  //通过  不拦截
                .and()
                .httpBasic()
                .and()
                .csrf().disable();    //csrf关闭    如果自定义登录  则需要关闭    csrf关闭跨域访问权限  安全   不会收到伪造的攻击
    }
}
